#include "curlclient.h"

// 静态成员初始化
std::once_flag CurlClient::s_initFlag;

// 响应回调函数实现
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s) {
    size_t newLength = size * nmemb;
    try {
        s->append((char*)contents, newLength);
    }
    catch (std::bad_alloc& e) {
        return 0; // 内存分配失败，停止接收
    }
    return newLength;
}

// 构造函数：初始化curl句柄
CurlClient::CurlClient() {
    // 确保全局初始化（线程安全）
    std::call_once(s_initFlag, &CurlClient::globalInit);

    // 初始化句柄
    m_curl = curl_easy_init();
    if (!m_curl) {
        throw std::runtime_error("curl句柄初始化失败");
    }

    // 设置默认回调和响应存储
    curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &m_response);
}

// 析构函数：清理资源
CurlClient::~CurlClient() {
    if (m_headers) {
        curl_slist_free_all(m_headers); // 释放HTTP头
    }
    if (m_curl) {
        curl_easy_cleanup(m_curl); // 释放curl句柄
    }
}

// 全局初始化curl（仅执行一次）
void CurlClient::globalInit() {
    curl_global_init(CURL_GLOBAL_ALL);
    // 可在此注册curl全局清理函数（程序退出时调用）
    // atexit(curl_global_cleanup);
}

// 发送JSON数据（核心方法，纯网络操作）
bool CurlClient::postJson(const std::string& json_data) {
    if (!m_curl || m_url.empty()) {
        m_error = "URL未设置或curl句柄无效";
        return false;
    }

    // 重置状态（支持重复使用实例）
    m_response.clear();
    m_error.clear();
    m_httpCode = 0;

    try {
        // 设置URL和超时
        curl_easy_setopt(m_curl, CURLOPT_URL, m_url.c_str());
        curl_easy_setopt(m_curl, CURLOPT_TIMEOUT, m_timeout);

        // HTTPS验证设置
        curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, m_sslVerify ? 1L : 0L);
        curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYHOST, m_sslVerify ? 2L : 0L);

        // 设置POST和JSON头
        curl_easy_setopt(m_curl, CURLOPT_POST, 1L);
        curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, json_data.c_str());

        // 重建HTTP头（避免重复添加）
        if (m_headers) {
            curl_slist_free_all(m_headers);
            m_headers = nullptr;
        }
        m_headers = curl_slist_append(m_headers, "Content-Type: application/json");
        curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, m_headers);

        // 执行请求
        CURLcode res = curl_easy_perform(m_curl);
        if (res != CURLE_OK) {
            m_error = std::string("请求失败: ") + curl_easy_strerror(res);
            // 获取HTTP状态码（即使请求失败也可能有状态码）
            curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &m_httpCode);
            return false;
        }

        // 获取HTTP状态码（成功时）
        curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &m_httpCode);
        return true;

    }
    catch (const std::exception& e) {
        m_error = std::string("异常: ") + e.what();
        return false;
    }
}
